﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using DJH.School.Application.Dtos;
using DJH.School.Common;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using DJH.School.Core.Models;
using DJH.School.EntityFramework;

namespace DJH.School.Controllers
{
    public class StudentsController : Controller
    {
        private readonly SchoolDbContext _context;

        public StudentsController(SchoolDbContext context)
        {
            _context = context;
        }

        // GET: Students
        public async Task<IActionResult> Index(string sortOrder, string searchStudent, int? page, string currentStudent)
        {
            //姓名的排序参数
            ViewData["Name_Sort_Param"] = string.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
            //时间的排序参数
            ViewData["Date_Sort_Param"] = sortOrder == "date" ? "date_desc" : "date";
            //搜索的关键字
            ViewData["SearchStudent"] = searchStudent;

            if (searchStudent != null)
            {
                page = 1;
            }
            else
            {
                searchStudent = currentStudent;
            }

            var students = from student in _context.Students select student;

            if (!string.IsNullOrWhiteSpace(searchStudent))
            {
                students = students.Where(a => a.RealName.Contains(searchStudent));
            }

            switch (sortOrder)
            {
                case "name_desc":
                    students = students.OrderByDescending(a => a.RealName);
                    break;
                case "date_desc":
                    students = students.OrderByDescending(a => a.EnrollmentDate);
                    break;
                case "date":
                    students = students.OrderBy(a => a.EnrollmentDate);
                    break;
                default:
                    students = students.OrderBy(a => a.RealName);
                    break;
            }

            int pageSize = 3;
            var entits = students.AsNoTracking();
            var dtos =await PaginatedList<Student>.CreatePagingAsync(entits, page ?? 1, pageSize);
            return View(dtos);
        }

        // GET: Students/Details/5
        public async Task<IActionResult> Details(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var student = await _context.Students.Include(a => a.Enrollments).ThenInclude(c => c.Course).AsNoTracking()
                .FirstOrDefaultAsync(m => m.Id == id);
            if (student == null)
            {
                return NotFound();
            }

            return View(student);
        }

        // GET: Students/Create
        public IActionResult Create()
        {
            return View();
        }

        // POST: Students/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Create(StudentDto student)
        {
            var entity = new Student();
            try
            {
                if (ModelState.IsValid)
                {
                    entity.RealName = student.RealName;
                    entity.EnrollmentDate = student.EnrollmentDate;
                    _context.Add(entity);
                    await _context.SaveChangesAsync();
                    return RedirectToAction(nameof(Index));
                }
            }
            catch (DbUpdateException e)
            {
                ModelState.AddModelError("", e.Message);
                Console.WriteLine(e);
                throw;
            }

            return View(entity);
        }

        // GET: Students/Edit/5
        public async Task<IActionResult> Edit(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            var student = await _context.Students.FindAsync(id);
            if (student == null)
            {
                return NotFound();
            }

            return View(student);
        }

        // POST: Students/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> Edit(int id, StudentDto student)
        {
            if (id != student.Id)
            {
                return NotFound();
            }

            var entity = await _context.Students.SingleOrDefaultAsync(a => a.Id == id);
            if (await TryUpdateModelAsync<Student>(entity, "", a => a.RealName, a => a.EnrollmentDate))
            {
                try
                {
                    await _context.SaveChangesAsync();
                    return RedirectToAction(nameof(Index));
                }
                catch (DbUpdateConcurrencyException e)
                {
                    ModelState.AddModelError("", e.Message);
                    throw;
                }
            }

            return View(entity);
        }

        // GET: Students/Delete/5
        public async Task<IActionResult> Delete(int? id, bool? saveChangesError = false)
        {
            if (id == null)
            {
                return NotFound();
            }

            var student = await _context.Students
                .FirstOrDefaultAsync(m => m.Id == id);
            if (student == null || saveChangesError.GetValueOrDefault())
            {
                ViewBag.SaveError = "删除失败";
            }

            return View(student);
        }

        // POST: Students/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> DeleteConfirmed(int id)
        {
            var student = await _context.Students.AsNoTracking().SingleOrDefaultAsync(m => m.Id == id);
            if (student == null)
            {
                return RedirectToAction(nameof(Delete), new {id, saveChangesError = true});
            }

            try
            {
                _context.Students.Remove(student);
                await _context.SaveChangesAsync();
                return RedirectToAction(nameof(Index));
            }
            catch (Exception)
            {
                return RedirectToAction(nameof(Delete), new {id, saveChangesError = true});
            }
        }

        private bool StudentExists(int id)
        {
            return _context.Students.Any(e => e.Id == id);
        }
    }
}